using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Reflection;
using System.Net.Mail;
using System.Xml;
using System.Web;
using System.Web.UI;

using DotNetNuke;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Users;
using DotNetNuke.Services.Mail;
using DotNetNuke.Services.Search;


namespace Jfc.DnnMarketingTools.MemberInvite
{
    /// -----------------------------------------------------------------------------
    ///<summary>
    /// The Controller class for the MemberInvite
    /// </summary>
    /// <remarks>
    /// </remarks>
    /// <history>
    /// </history>
    /// -----------------------------------------------------------------------------
    public class MemberInviteController : ISearchable, IPortable
    {

    #region Constructors

        public MemberInviteController()
        {
        }

    #endregion

    #region Public Methods

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// adds an object to the database
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="objMemberInvite">The MemberInviteInfo object</param>
        /// <history>
        /// </history>
        /// -----------------------------------------------------------------------------
        public void AddMemberInvite(MemberInviteInfo objMemberInvite)
        {
            if (!String.IsNullOrEmpty(objMemberInvite.FirstName) &&
                !String.IsNullOrEmpty(objMemberInvite.Email) &&
                !String.IsNullOrEmpty(objMemberInvite.Subject) &&
                !String.IsNullOrEmpty(objMemberInvite.Body))
            {
                DataProvider.Instance().AddMemberInvite(objMemberInvite.PortalId, objMemberInvite.InviteGuid, objMemberInvite.FirstName, objMemberInvite.LastName, objMemberInvite.Email, objMemberInvite.Subject, objMemberInvite.Body, objMemberInvite.CreatedByUser, (int)objMemberInvite.Status);
            }
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// deletes an object from the database
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="ModuleId">The Id of the module</param>
        /// <param name="ItemId">The Id of the item</param>
        /// <history>
        /// </history>
        /// -----------------------------------------------------------------------------
        public void DeleteMemberInvite(int InviteId, int PortalId) 
        {
            DataProvider.Instance().DeleteMemberInvite(InviteId,PortalId);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// gets an object from the database
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="moduleId">The Id of the module</param>
        /// <param name="ItemId">The Id of the item</param>
        /// <history>
        /// </history>
        /// -----------------------------------------------------------------------------
        public MemberInviteInfo GetMemberInvite(int InviteId, int PortalId)
        {
            return CBO.FillObject < MemberInviteInfo >(DataProvider.Instance().GetMemberInvite(InviteId, PortalId));
        }


        /// -----------------------------------------------------------------------------
        /// <summary>
        /// gets an object from the database
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="InviteGuid">The Guid of the item</param>
        /// <history>
        /// </history>
        /// -----------------------------------------------------------------------------
        public MemberInviteInfo GetMemberInviteByGuid(Guid InviteGuid)
        {
            return CBO.FillObject<MemberInviteInfo>(DataProvider.Instance().GetMemberInviteByGuid(InviteGuid));
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// gets an object from the database
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="moduleId">The Id of the module</param>
        /// <history>
        /// </history>
        /// -----------------------------------------------------------------------------
        public List<MemberInviteInfo> GetMemberInvites(int PortalId)
        {
            return CBO.FillCollection< MemberInviteInfo >(DataProvider.Instance().GetMemberInvites(PortalId));
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// gets an object from the database
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="moduleId">The Id of the module</param>
        /// <history>
        /// </history>
        /// -----------------------------------------------------------------------------
        public List<MemberInviteInfo> GetMemberInvitesForUser(int portalId, int userId)
        {
            return CBO.FillCollection<MemberInviteInfo>(DataProvider.Instance().GetMemberInvitesForUser(portalId, userId));
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// saves an object to the database
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="objMemberInvite">The MemberInviteInfo object</param>
        /// <history>
        /// </history>
        /// -----------------------------------------------------------------------------
        public void UpdateMemberInvite(MemberInviteInfo objMemberInvite)
        {
            if (!String.IsNullOrEmpty(objMemberInvite.FirstName) &&
                !String.IsNullOrEmpty(objMemberInvite.Email) &&
                !String.IsNullOrEmpty(objMemberInvite.Subject) &&
                !String.IsNullOrEmpty(objMemberInvite.Body))
            {
                DataProvider.Instance().UpdateMemberInvite(objMemberInvite.InviteId, objMemberInvite.PortalId, objMemberInvite.InviteGuid, objMemberInvite.FirstName, objMemberInvite.LastName, objMemberInvite.Email, objMemberInvite.Subject, objMemberInvite.Body, objMemberInvite.CreatedByUser, (int)objMemberInvite.Status, objMemberInvite.StatusDate);
            }
        }

    #endregion

        static public string ReplaceProperties(string text, MemberInviteInfo memberInvite, PortalSettings portalSettings, UserInfo userInfo)
        {
            string value = Null.NullString;

            // MemberInviteInfo

            ArrayList properties = CBO.GetPropertyInfo(typeof(MemberInviteInfo));

            foreach (PropertyInfo propertyInfo in properties)
            {
                if (text.IndexOf("[Invite:" + propertyInfo.Name + "]") != -1)
                {
                    value = DataBinder.Eval(memberInvite, propertyInfo.Name).ToString();
                    text = text.Replace("[Invite:" + propertyInfo.Name + "]", value);
                }
            }

            // PortalSettings

            properties = CBO.GetPropertyInfo(typeof(PortalSettings));

            foreach (PropertyInfo propertyInfo in properties)
            {
                if (text.IndexOf("[Portal:" + propertyInfo.Name + "]") != -1)
                {
                    value = DataBinder.Eval(portalSettings, propertyInfo.Name).ToString();
                    text = text.Replace("[Portal:" + propertyInfo.Name + "]", value);
                }
            }

            // PortalSettings.PortalAliasInfo

            properties = CBO.GetPropertyInfo(typeof(PortalAliasInfo));

            foreach (PropertyInfo propertyInfo in properties)
            {
                if (text.IndexOf("[Portal:" + propertyInfo.Name + "]") != -1)
                {
                    value = DataBinder.Eval(portalSettings.PortalAlias, propertyInfo.Name).ToString();
                    text = text.Replace("[Portal:" + propertyInfo.Name + "]", value);
                }
            }

            // UserInfo

            properties = CBO.GetPropertyInfo(typeof(UserInfo));

            foreach (PropertyInfo propertyInfo in properties)
            {
                if (text.IndexOf("[User:" + propertyInfo.Name + "]") != -1)
                {
                    value = DataBinder.Eval(userInfo, propertyInfo.Name).ToString();
                    text = text.Replace("[User:" + propertyInfo.Name + "]", value);
                }
            }

            return text;
        }

        static private bool SendMail(MailAddress mailFrom, MemberInviteInfo memberInvite)
        {
            string mailToDisplayName = memberInvite.FirstName;
            if(!String.IsNullOrEmpty(memberInvite.LastName))
                mailToDisplayName += " " + memberInvite.LastName;

            System.Net.Mail.MailAddress mailTo = new System.Net.Mail.MailAddress(memberInvite.Email, mailToDisplayName);

            string error = Mail.SendMail(mailFrom.ToString(), mailTo.ToString(), "", memberInvite.Subject, memberInvite.Body, "", "", "", "", "", "");

            if (String.IsNullOrEmpty(error))
                return true;

            return false;
        }

        public void Send(MemberInviteInfo objMemberInvite, SenderAddressType senderAddress, PortalSettings portalSettings, UserInfo userInfo)
        {
            objMemberInvite.Subject = MemberInviteController.ReplaceProperties(objMemberInvite.Subject, objMemberInvite, portalSettings, userInfo);
            objMemberInvite.Body = MemberInviteController.ReplaceProperties(objMemberInvite.Body, objMemberInvite, portalSettings, userInfo);

            MemberInviteSettingsController controller = new MemberInviteSettingsController();
            MemberInviteSettingsInfo memberInviteSettings = controller.GetMemberInviteSettings(portalSettings.PortalId, userInfo.UserID);
                
            MailAddress mailFrom;

            if (senderAddress == SenderAddressType.User)
                mailFrom = new MailAddress(userInfo.Email, userInfo.DisplayName);
            else
                mailFrom = new MailAddress(portalSettings.Email, portalSettings.PortalName);

            if (SendMail(mailFrom, objMemberInvite))
                objMemberInvite.SetStatus(StatusType.Sent);
            else
                objMemberInvite.SetStatus(StatusType.Bounced);

            UpdateMemberInvite(objMemberInvite);
        }

        /*
        public void SendAllRegistered(int portalId)
        {
            List<MemberInviteInfo> colMemberInvites = GetMemberInvites(portalId);

            foreach (MemberInviteInfo objMemberInvite in colMemberInvites)
            {
                if (objMemberInvite != null && objMemberInvite.Status == StatusType.Registered)
                {
                    Send(portalId, objMemberInvite);
                }
            }
        }
        */

        #region Optional Interfaces
        
        /// -----------------------------------------------------------------------------
        /// <summary>
        /// GetSearchItems implements the ISearchable Interface
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="ModInfo">The ModuleInfo for the module to be Indexed</param>
        /// <history>
        /// </history>
        /// -----------------------------------------------------------------------------
        public SearchItemInfoCollection GetSearchItems(ModuleInfo ModInfo)
        {
            SearchItemInfoCollection SearchItemCollection = new SearchItemInfoCollection();
            List<MemberInviteInfo> colMemberInvites  = GetMemberInvites(ModInfo.PortalID);

            foreach (MemberInviteInfo objMemberInvite in colMemberInvites)
            {
                if(objMemberInvite != null)
                {
                    SearchItemInfo SearchItem = new SearchItemInfo(ModInfo.ModuleTitle, objMemberInvite.Body, objMemberInvite.CreatedByUser, objMemberInvite.CreatedDate, ModInfo.ModuleID, objMemberInvite.InviteId.ToString(), objMemberInvite.Body, "ItemId=" + objMemberInvite.InviteId.ToString());
                    SearchItemCollection.Add(SearchItem);
                }
            }

            return SearchItemCollection;
        }


        /// -----------------------------------------------------------------------------
        /// <summary>
        /// ExportModule implements the IPortable ExportModule Interface
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="ModuleID">The Id of the module to be exported</param>
        /// <history>
        /// </history>
        /// -----------------------------------------------------------------------------
        public string ExportModule(int PortalID)
        {
            string strXML = "";
            List<MemberInviteInfo> colMemberInvites  = GetMemberInvites(PortalID);

            if (colMemberInvites.Count != 0)
            {
                strXML += "<MemberInvites>";
                foreach (MemberInviteInfo objMemberInvite in colMemberInvites)
                {
                    strXML += "<MemberInvite>";
                    strXML += "<InviteGuid>" + XmlUtils.XMLEncode(objMemberInvite.InviteGuid.ToString()) + "</InviteGuid>";
                    strXML += "<FirstName>" + XmlUtils.XMLEncode(objMemberInvite.FirstName) + "</FirstName>";
                    strXML += "<LastName>" + XmlUtils.XMLEncode(objMemberInvite.LastName) + "</LastName>";
                    strXML += "<Email>" + XmlUtils.XMLEncode(objMemberInvite.Email) + "</Email>";
                    strXML += "<Subject>" + XmlUtils.XMLEncode(objMemberInvite.Subject) + "</Subject>";
                    strXML += "<Body>" + XmlUtils.XMLEncode(objMemberInvite.Body) + "</Body>";
                    strXML += "<Status>" + XmlUtils.XMLEncode(Convert.ToString((int)objMemberInvite.Status)) + "</Status>";
                    //strXML += "<StatusDate>" + XmlUtils.XMLEncode(objMemberInvite.StatusDate) + "</StatusDate>";
                    strXML += "</MemberInvite>";
                }
                strXML += "</MemberInvites>";
            }

            return strXML;
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// ImportModule implements the IPortable ImportModule Interface
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="ModuleID">The Id of the module to be imported</param>
        /// <param name="Content">The content to be imported</param>
        /// <param name="Version">The version of the module to be imported</param>
        /// <param name="UserId">The Id of the user performing the import</param>
        /// <history>
        /// </history>
        /// -----------------------------------------------------------------------------
        public void ImportModule(int PortalID, string Content, string Version, int UserId)
        {
            XmlNode xmlMemberInvites = Globals.GetContent(Content, "MemberInvites");

            foreach (XmlNode xmlMemberInvite in xmlMemberInvites.SelectNodes("MemberInvite"))
            {
                MemberInviteInfo objMemberInvite = new MemberInviteInfo();

                objMemberInvite.PortalId = PortalID;
                objMemberInvite.InviteGuid = new Guid(xmlMemberInvite.SelectSingleNode("InviteGuid").InnerText);
                objMemberInvite.FirstName = xmlMemberInvite.SelectSingleNode("FirstName").InnerText;
                objMemberInvite.LastName = xmlMemberInvite.SelectSingleNode("LastName").InnerText;
                objMemberInvite.Email = xmlMemberInvite.SelectSingleNode("Email").InnerText;
                objMemberInvite.Subject = xmlMemberInvite.SelectSingleNode("Subject").InnerText;
                objMemberInvite.Body = xmlMemberInvite.SelectSingleNode("Body").InnerText;
                objMemberInvite.Status = (StatusType)Convert.ToInt32(xmlMemberInvite.SelectSingleNode("Status").InnerText);
                //objMemberInvite.StatusDate = xmlMemberInvite.SelectSingleNode("StatusDate").InnerText;
                objMemberInvite.CreatedByUser = UserId;
                AddMemberInvite(objMemberInvite);
            }

}

    #endregion

    }
}

